<script setup lang="ts">
import { ref, onMounted } from 'vue';
import * as THREE from 'three';

//控制x轴波浪的长度
const amountX = 50;
//控制y轴波浪的长度
const amountY = 50;

const SEPARATION = 100;
let container, camera: THREE.Camera, scene: THREE.Scene, renderer: THREE.WebGLRenderer;
let particles: THREE.Object3D<THREE.Object3DEventMap>;
let count = 0;
let mouseX = 0;

// 初始化函数
const init = () => {
    container = document.createElement("div");
    document.getElementById("iviewBg")?.appendChild(container);

    //创建透视相机
    camera = new THREE.PerspectiveCamera(
        75, //摄像机视锥体垂直视野角度
        window.innerWidth / window.innerHeight, //摄像机视锥体长宽比
        1, //摄像机视锥体近端面
        10000 //摄像机视锥体远端面
    );

    //设置相机z轴视野
    camera.position.z = 1000;

    //创建场景
    scene = new THREE.Scene();

    const numParticles = amountX * amountY;

    //类型化数组创建顶点数据
    const positions = new Float32Array(numParticles * 10);
    const scales = new Float32Array(numParticles);

    let i = 0, j = 0;
    // 初始化粒子位置和大小
    for (let ix = 0; ix < amountX; ix++) {
        for (let iy = 0; iy < amountY; iy++) {
            positions[i] = ix * SEPARATION - (amountX * SEPARATION) / 2; // x
            positions[i + 1] = 0; // y
            positions[i + 2] = iy * SEPARATION - (amountY * SEPARATION) / 2; // z
            scales[j] = 1;
            i += 3;
            j++;
        }
    }

    //创建一个空的几何体对象
    const geometry = new THREE.BufferGeometry();
    geometry.setAttribute(
        "position",
        // 创建属性缓冲区对象
        //3个为一组，表示一个顶点的xyz坐标
        new THREE.BufferAttribute(positions, 3)
    );
    geometry.setAttribute("scale", new THREE.BufferAttribute(scales, 1));

    //着色器材质(ShaderMaterial),设置球的大小，颜色等
    const material = new THREE.ShaderMaterial({
        uniforms: {
            //设置球的颜色
            color: { value: new THREE.Color("#097bdb") },
        },
        //控制球的大小
        vertexShader:
            "attribute float scale; void main() {vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );gl_PointSize = scale * ( 300.0 / - mvPosition.z );gl_Position = projectionMatrix * mvPosition;}",
        fragmentShader:
            "uniform vec3 color;void main() {if ( length( gl_PointCoord - vec2( 0.5, 0.5 ) ) > 0.475 ) discard;gl_FragColor = vec4( color, 1.0 );}",
    });

    //一个用于显示点的类。
    particles = new THREE.Points(geometry, material);
    //往场景中添加点
    scene.add(particles);

    // 创建渲染器对象
    // 设置渲染器锯齿属性  背景透明
    renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
    //设置three.js渲染区域的尺寸(像素px)
    renderer.setSize(window.innerWidth / 2, window.innerHeight / 2);
    // 获得渲染方法，生成的Canvas画布
    container.appendChild(renderer.domElement);
};

// 渲染函数
const render = () => {
    // 相机位置
    camera.position.x += (mouseX - camera.position.x) * 0.05;
    camera.position.y = 500;
    // .position改变，重新执行lookAt计算相机视线方向
    camera.lookAt(scene.position);

    const positions = particles.geometry.attributes.position.array;
    const scales = particles.geometry.attributes.scale.array;

    // 设置粒子位置和大小
    let i = 0, j = 0;
    for (let ix = 0; ix < amountX; ix++) {
        for (let iy = 0; iy < amountY; iy++) {
            positions[i + 1] =
                Math.sin((ix + count) * 0.5) * 50 +
                Math.sin((iy + count) * 0.5) * 50;

            scales[j] =
                (Math.sin((ix + count) * 0.3) + 1) * 10 +
                (Math.sin((iy + count) * 0.5) + 1) * 10;

            i += 3;
            j++;
        }
    };

    // 场景 相机
    renderer.render(scene, camera);
    count += 0.1;
}

onMounted(() => {
    init();
    render();
});
</script>

<template>
    <div class="center-container">
        <div class="iframe-box">
            <!-- iframe 一种将其他网页内容嵌入到当前页面的方式 -->
            <!-- frameborder 控制是否显示边框，0 表示不显示 -->
            <iframe width="100%" height="150%" src="https://api.bimface.com/preview/e6fbbd29?viewid=1244"
                frameborder="0"></iframe>
        </div>
        <div id="iviewBg">

        </div>
    </div>
</template>

<style scoped lang="scss">
.center-container {
    width: 34vw;
    height: 100vh;
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    top: 0;
    z-index: 100;

    .iframe-box {
        width: 95%;
        height: 50%;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translateX(-50%) translateY(-50%);
        overflow: hidden;
        position: relative;
        z-index: 300;

        iframe {
            position: absolute;
            top: -15%;
        }
    }

    // #iviewBg {}
}
</style>